package designPattern.composite
{
	public class Composite extends BaseComponent
	{
		private var sName:String;
		private var children:Array;
		public function Composite(sName:String)
		{
			this.sName = sName;
			children = [];
		}
		
		override public function add(c:IBaseComponent):void
		{
			children.push(c);
			(c as BaseComponent).setParent(this);//向下转型
		}
		
		override public function getChild(n:int):IBaseComponent
		{
			if(n > 0 && n <= children.length)
			{
				return children[n - 1];
			}
			return null;
		}
		
		override internal function isComposite():Boolean
		{
			return true;
		}
		
		/**
		 * 移除节点的时候必须移除他所有的引用！！！！！
		 * 这样垃圾回收才能真正清除 
		 * 三点重要：
		 * #移除该节点的父节点的引用
		 * #区分是组件节点还是叶子节点
		 * #针对不同类型的节点删除方式也不同
		 * @param c
		 * 
		 */		
		override public function remove(c:IBaseComponent):void
		{
			if(c == this)
			{//移除自己
				//移除所有孩子节点
				for(var i:int = 0; i < children.length; i++)
				{
					safeRemove(children[i]);
				}
				//移除对孩子节点的引用
				this.children = [];
				//移除父节点
				this.remParentRef();
			}
			else
			{//移除子节点
				for(var j:int = 0; j < children.length; j++)
				{
					if(children[j] == c)
					{
						safeRemove(c);
						children.splice(j, 1);
					}
				}
			}
		}
		
		private function safeRemove(c:IBaseComponent):void
		{
			if((c as BaseComponent).isComposite())
			{//是组件节点
				c.remove(c);
			}
			else
			{//是叶子节点
				(c as BaseComponent).remParentRef();
			}
		}
		
		override public function operate():void
		{
			trace(this.sName);
			for each(var c:IBaseComponent in children)
			{
				c.operate();
			}
		}
	}
}